/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ayuda;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.*;
import tesauro.DiccionarioSinonimos;

/**
 * Clase que mantiene un mapa de topicos y un diccionario de sinonimos de esos
 * topicos que relaciona cada topico con palabras claves del mismo.
 *
 * Esta clase se implementa como un singleton.
 */
public class Ayuda {
    DiccionarioSinonimos palabrasClave;
    HashMap topicos;
    private ICargadorAyuda cargadorAyuda;
    private boolean inicializada;
    private static Ayuda instancia;

    private Ayuda() {
        palabrasClave = new DiccionarioSinonimos();
        topicos = new HashMap();
        cargadorAyuda = new CargadorArchivoTextoAyuda(new File(System.getProperty("user.dir") +
                                                                                             File.separator + "data" + File.separator + "ayuda.txt"));
    }

    /**
     * Obtiene le singleton Ayuda.
     *
     * @return unica instancia de ayuda.
     */
    public static Ayuda getInstancia() {
        if(instancia == null) {
            instancia = new Ayuda();
        }

        return instancia;
    }

    /**
     * Carga la ayuda usando el cargador por defecto que se 
     * setea al crear una isntancia de ayuda.
     * 
     * @throws java.lang.Exception si hubo problemas al cargar la ayuda 
     * desde el archivo.
     */
    public void cargar() throws Exception {
        cargadorAyuda.cargar(this);
        inicializada = true;
    }

    /**
     * Obtiene un topico segun palabra clave.
     *
     * @param palabraClave palabra clavo del topico o nombre del topico.
     * @return el texto del topico o null si no hay topico con la
     * palabra clave o no existe el topico.
     */
    public String getTopico(String palabraClave) {
        ArrayList<String> sinonimos =(ArrayList<String>) palabrasClave.getSinonimosDe(palabraClave);

        if(sinonimos == null) {
            sinonimos = new ArrayList<String>(1);
        }

        sinonimos.add(palabraClave);

        String topico = null;
        for(String sinonimo : sinonimos) {
            topico = (String)topicos.get(sinonimo);
            if(topico != null) {
                break;
            }
        }

        return topico;
    }

    public boolean inicializada() {
       return inicializada;
    }
}

/**
 * Clase por defecto que parsea un archivo de texto
 * con la ayuda.
 */
class CargadorArchivoTextoAyuda implements ICargadorAyuda {
    private File archivo;
    private  LineNumberReader br = null;
    private String palabra;
    private StringBuffer topico;
    public static String CABECERA = "[ayuda]";

    public CargadorArchivoTextoAyuda(File archivo) {
         this.archivo = archivo;
    }

    public void cargar(Ayuda ayuda) throws Exception {
        try {
            br = new LineNumberReader(new FileReader(archivo));
            StringBuffer line = new StringBuffer();
            line.append(proximaLineaValida());
            if (!line.toString().equals(CABECERA)) {
                return;
            }

            line.delete(0, line.length());
            line.append(proximaLineaValida());
            while(!line.toString().equals("null")) {
                if(line.charAt(0) == '[') {
                    if(!line.substring(1, 4).equals("fin"))
                    {
                        line.replace(0, 1, "");
                        line.replace(line.length() - 1, line.length(), "");

                        //trim a la subcadena luego del ":". asi evito usar String.
                        for(int i = 0; i < line.length(); i++) {
                            if(line.charAt(i) == ':' || line.charAt(i) == ',') {
                                int espacios = 0;
                                while(line.charAt((i + 1) + espacios) == ' ') {
                                    line.deleteCharAt((i + 1) + espacios);
                                    espacios++;
                                }
                            }
                        }

                        String splitted[] = line.toString().split(":");
                        palabra = splitted[0].trim();
                        String sinonimosArray[] = splitted[1].split(",");
                        
                        ayuda.palabrasClave.recursiveAdd(palabra, Arrays.asList(sinonimosArray));
                    }
                } else {
                        while(line.charAt(0) != '[')
                        {
                            if(topico == null) {
                                topico = new StringBuffer();
                            }

                            topico.append(line + "\n");
                            line.delete(0, line.length());
                            line.append(proximaLineaValida());
                        }
                        
                        ayuda.topicos.put(palabra, topico.toString());
                        topico.delete(0, topico.length());
                }

                line.delete(0, line.length());
                line.append(proximaLineaValida());
            }
        } catch(FileNotFoundException ex) {
            ex.printStackTrace();
            throw new Exception("No se encontro el archivo de ayuda.");
        } catch (IOException ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

    /**
     * 
     * @return
     * @throws java.io.IOException
     */
    private String proximaLineaValida() throws IOException {
            String line = null;
            String tmpLine = null;
            while((line = br.readLine()) != null) {
                tmpLine = line.trim();
                if(!tmpLine.isEmpty() && !tmpLine.startsWith("//")) {
                    break;
                }
            }

            return line;
    }
}